using System;
using System.Linq.Expressions;

namespace Charisma.Linq
{
  public sealed class ParameterExtractor : ExpressionVisitor
  {
    private readonly ExpressionEvaluator evaluator;
    private bool isParameter;

    public bool IsParameter(Expression e)
    {
      if (!evaluator.CanBeEvaluated(e))
        return false;
      isParameter = false;
      Visit(e);
      return isParameter;
    }

    public Expression<Func<T>> ExtractParameter<T>(Expression expression)
    {
      if (expression.NodeType == ExpressionType.Lambda)
        return (Expression<Func<T>>)expression;
      Type type = expression.Type;
      if (type.IsValueType)
        expression = Expression.Convert(expression, typeof(T));
      var lambda = Expression.Lambda<Func<T>>(expression);
      return lambda;
    }

    protected override Expression VisitMember(MemberExpression m)
    {
      isParameter = true;
      return base.VisitMember(m);
    }

    public ParameterExtractor(ExpressionEvaluator evaluator)
    {
      this.evaluator = evaluator;
    }
  }
}